package com.infolab.aims.web;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.StringWriter;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.time.DateFormatUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.codehaus.jackson.JsonGenerator;
import org.codehaus.jackson.map.ObjectMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.SessionAttributes;

import com.infolab.aims.GlobalConstant;
import com.infolab.aims.common.AbstractController;
import com.infolab.aims.common.CommonUtil;
import com.infolab.aims.common.exception.ResourceNotFoundException;
import com.infolab.aims.domain.Report;
import com.infolab.aims.service.intf.ReportService;


@Controller
@RequestMapping("/report")
@SessionAttributes(value=ReportController.SESSION_SEARCH_CRITERIA)
public class ReportController extends AbstractController {
	
	public static final String SESSION_SEARCH_CRITERIA ="searchCriteria";
	public static final String CONTEXT_PATH ="/report";
	public static final String JSP_MAIN_FORM="reportForm";
	public static final String JSP_PROCESSING ="reportProcessing";
	public static final String JSP_MAIN_SEARCH="reportSearch";
	

	@Autowired
	ReportService reportService;
	
	Log logger = LogFactory.getLog(getClass());
	

	@RequestMapping(value="create/{module}/{subModule}", method = RequestMethod.GET)
	public String createReport(@PathVariable String module,@PathVariable String subModule,Model model) {
		
		if(!Report.isValidModule(module, subModule))
			throw new ResourceNotFoundException("Report " + module+"/"+subModule);
		
		Report report = new Report();
		report.setModule(module);
		report.setSubModule(subModule);
		Map<String,String> search = new HashMap<String, String>();
	
//		if(StringUtils.equalsIgnoreCase("R01", subModule))
//		{
//			search.put("date", DateFormatUtils.format(new Date(), "MM/yyyy"));
//		}
//		if(StringUtils.equalsIgnoreCase("R02", subModule))
//		{
//			search.put("date", DateFormatUtils.format(new Date(), "MM/yyyy"));
//		}
//		if(StringUtils.equalsIgnoreCase("R03", subModule))
//		{
//			search.put("date", DateFormatUtils.format(new Date(), "dd/MM/yyyy"));
//		}
//		if(StringUtils.equalsIgnoreCase("R04", subModule))
//		{
//			search.put("date", DateFormatUtils.format(new Date(), "MM/yyyy"));
//		}
//		
		
		report.setSearch(search);
		model.addAttribute(report);
		model.addAttribute("module",module);
		model.addAttribute("subModule",subModule);
		
		return JSP_MAIN_FORM;
	}
	
	@RequestMapping(value="create/{module}/{subModule}", method = RequestMethod.POST)
	public String saveReport(@PathVariable String module,@PathVariable String subModule,@ModelAttribute Report report, BindingResult result,Model model,HttpServletRequest request) {

	
		Map<String,String> paramSearch = report.getSearch();
		
		StringWriter writer = new StringWriter();
        ObjectMapper mapper = new ObjectMapper();
        JsonGenerator jsonGenerator;
		try {
			jsonGenerator = mapper.getJsonFactory().createJsonGenerator(writer);
			mapper.writeValue(jsonGenerator, paramSearch);
			report.setParamSearch(writer.toString());
		} catch (IOException e) {
			logger.error(CommonUtil.getStackTrace(e));
		}
		
		report.setCreatedBy(getCurrentUserName(request));
		
		
		reportService.createNewReport(report);
		
		reportService.processReport(report);
		
		return "redirect:"+CONTEXT_PATH+"/show/" + report.getReportId();
		
	}
	
	
	@RequestMapping(value="show/{reportId}", method = RequestMethod.GET)
	public String showReport(@PathVariable String reportId, Model model,HttpServletRequest request) {

		Report report = reportService.getReport(reportId);
		if(report==null) {
			throw new ResourceNotFoundException("Report " + reportId);
		}
		model.addAttribute(report);
		return JSP_PROCESSING;
	}
	
	@RequestMapping(value="download/{reportId}", method = RequestMethod.GET)
	public void downloadReport(@PathVariable String reportId, Model model,HttpServletResponse response) throws IOException {

		Report report = reportService.getReport(reportId);
		if(report==null) {
			throw new ResourceNotFoundException("Report " + reportId);
		}
		
		ServletOutputStream outputStream = response.getOutputStream();
		
		if(report.isPdfReport())
			response.setContentType(GlobalConstant.MIME_PDF);
		else
			response.setContentType(GlobalConstant.MIME_XLS);
		
		FileInputStream fis = new FileInputStream(reportService.getReportDirectory()+File.separatorChar+report.getReportFileName());
		if(fis==null)
		{
			logger.warn("Report file not found  : " + reportService.getReportDirectory()+File.separatorChar+report.getReportFileName());		
		}
		else
		{
			logger.info("Download report file :  " + reportService.getReportDirectory()+File.separatorChar+report.getReportFileName());
			byte[] bbuf = new byte[1024];
			int length   = 0;
	        while (((length = fis.read(bbuf)) != -1))
	        {
	        	outputStream.write(bbuf,0,length);
	        }
	        outputStream.flush();
	        outputStream.close();
	        fis.close();
		}
	}
}
